/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.hop.www;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.hop.core.Const;
import org.apache.hop.core.variables.IVariables;
import org.apache.hop.core.xml.XmlHandler;
import org.apache.hop.i18n.PackageMessages;
import org.owasp.encoder.Encode;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public abstract class BodyHttpServlet extends BaseHttpServlet implements IHopServerPlugin {

  private static final long serialVersionUID = 6576714217004890327L;
  private final PackageMessages messages;

  public BodyHttpServlet() {
    messages = new PackageMessages(this.getClass());
  }

  protected boolean useXML(HttpServletRequest request) {
    return "Y".equalsIgnoreCase(request.getParameter("xml"));
  }

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
    if (isJettyMode() && !request.getContextPath().startsWith(getContextPath())) {
      return;
    }

    if (log.isDebug()) {
      logDebug(messages.getString("Log.Execute"));
    }

    boolean useXML = useXML(request);
    PrintWriter out = new PrintWriter(response.getOutputStream());

    try {

      if (useXML) {
        startXml(response, out);
      } else {
        beginHtml(response, out);
      }

      WebResult result = generateBody(request, response, useXML, variables);
      if (result != null) {
        out.println(result.getXml());
      }

    } catch (Exception e) {
      String st = ExceptionUtils.getFullStackTrace(e);
      if (useXML) {
        out.println(new WebResult(WebResult.STRING_ERROR, st).getXml());
      } else {
        out.println("<p><pre>");
        out.println(Encode.forHtml(st));
        out.println("</pre>");
      }
    } finally {
      if (!useXML) {
        endHtml(out);
      }
      out.flush();
      IOUtils.closeQuietly(out);
    }
  }

  protected void beginHtml(HttpServletResponse response, PrintWriter out) throws IOException {
    response.setContentType("text/html;charset=UTF-8");
    out.println("<HTML>");
    out.println("<HEAD>");
    out.println("<TITLE>");
    out.println(Encode.forHtml(getTitle()));
    out.println("</TITLE>");
    out.println("<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
    out.println("</HEAD>");
    out.println("<BODY>");
  }

  protected void endHtml(PrintWriter out) {
    out.println("<p>");
    out.println("</BODY>");
    out.println("</HTML>");
  }

  protected void startXml(HttpServletResponse response, PrintWriter out) throws IOException {
    response.setContentType("text/xml");
    response.setCharacterEncoding(Const.XML_ENCODING);
    out.print(XmlHandler.getXmlHeader(Const.XML_ENCODING));
  }

  abstract WebResult generateBody(
      HttpServletRequest request,
      HttpServletResponse response,
      boolean useXML,
      IVariables variables)
      throws Exception;

  @Override
  public String getService() {
    return getContextPath() + " (" + getTitle() + ")";
  }

  private String getTitle() {
    return messages.getString("Title");
  }
}
